package com.example.app1.util;

import android.content.SharedPreferences;

import com.example.app1.LogUtil;
import com.example.app1.service.MyTextToSpeechService;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 监听缓存变化,根据缓存的变化，触发相应动作，是程序的控制中心
 * 下一章：PlayThread当播放下一章时，会更新缓存中的 REQ_ID
 * REQ_ID: 请求章节内容，并更新到 playThread 播放内容队列
 */
public class CacheChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener {
    private static final String TAG = "CacheChangeListener";

    Pattern pattern = Pattern.compile("<.*?>");
    private final HandleTts handleTts;
    private final MyTextToSpeechService service;

    // 创建一个固定大小的线程池，大小为3
    ExecutorService executor = Executors.newFixedThreadPool(3);

    public CacheChangeListener(HandleTts handleTts, MyTextToSpeechService service) {
        this.handleTts = handleTts;
        this.service = service;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//        LogUtil.info(TAG, key + " change: " + key);
        CacheKey cacheKey = CacheKey.valueOf(key);
        switch (cacheKey) {
            case REQ_INC:
                String regItemId = sharedPreferences.getString(CacheKey.REQ_ID.name(), null);
                if (regItemId == null || regItemId.trim().isEmpty() || "null".equals(regItemId)) {
                    LogUtil.info(TAG, "################regId null");
                    return;
                }
                // 先开线程缓存下一单
                this.executor.execute(() -> cacheItem(sharedPreferences, sharedPreferences.getString(CacheKey.PRE_URL.name(), "http://8.138.130.26/n/novel/getItemContent?itemId=") + regItemId, 3));

                break;
            case CURRENT_TITLE:
            case STATUS:
                notifyStatus(sharedPreferences);
                break;
            case CURRENT_ID:
                break;
            case Show_PAUSE:
                boolean isShow = sharedPreferences.getBoolean(CacheKey.Show_PAUSE.name(), false);
                this.service.changePauseButtonStatus(isShow);
                break;
            case MSG:
                this.service.showToast(sharedPreferences.getString(CacheKey.MSG.name(), "未获取到消息"));
                break;
            case CURRENT_IDX:
                this.service.setCurrentIdx(sharedPreferences.getString(CacheKey.CURRENT_IDX.name(), ""));
                break;
            case CURRENT_CONTENT:
                String currentId = sharedPreferences.getString(CacheKey.CURRENT_ID.name(), "");
                this.service.showContentToView(sharedPreferences.getString(CacheKey.CURRENT_CONTENT.name(), ""), currentId);
                break;
            case PLAY_AT_IDX:
                int idx = sharedPreferences.getInt(CacheKey.PLAY_AT_IDX.name(), -1);
                if (idx == -1) {
                    return;
                } else {
                    CacheUtil.writePlayAtIdx(sharedPreferences, false, -1);  // 用完了就还原
                    HandleCommand.playAt(sharedPreferences, this.handleTts, idx);
                }

        }
    }

    private void notifyStatus(SharedPreferences sharedPreferences) {
        String title = sharedPreferences.getString(CacheKey.CURRENT_TITLE.name(), "");
        String text;
        String status = sharedPreferences.getString(CacheKey.STATUS.name(), PlayStatus.READY.name());
        PlayStatus playStatus = PlayStatus.valueOf(status);
        switch (playStatus) {
            case STOP:
                text = "已停止";
                break;
            case READY:
                text = "就绪";
                break;
            case PLAYING:
                text = "播放中";
                break;
            case PAUSE:
                text = "已暂停";
                break;
            default:
                text = "已就绪";
        }
        this.service.updateNotify(title, text);
    }

    /**
     * 缓存章节
     * @param reqUrl 接口url
     * @param tryCount 重试次数
     */
    private synchronized void cacheItem(SharedPreferences sharedPreferences, String reqUrl, int tryCount) {
        try {
            URL url = new URL(reqUrl);
            LogUtil.info(TAG, "req " + url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = reader.readLine()) != null) {
                response.append(inputLine);
            }
            reader.close();
            connection.disconnect();

            JSONObject json = new JSONObject(response.toString());
            JSONObject data = json.getJSONObject("data");
            String content = data.has("content")?data.getString("content"):"";
            JSONObject novelItem = data.getJSONObject("novelItem");
            String nextId = novelItem.has("nextId")?novelItem.getString("nextId"):"";
            String preId = novelItem.has("preId")?novelItem.getString("preId"):"";
            String id = novelItem.has("id")?novelItem.getString("id"):"";
            String title = novelItem.getString("title");

            Matcher matcher = pattern.matcher(content);

            // 查找匹配的标签并输出
            Set<String> tags = new HashSet<>();
            while (matcher.find()) {
                tags.add(matcher.group());
            }

            content = content.replace("&nbsp;", "  ");
            for (String tag:tags) {
                if (tag == null) {
                    continue;
                }
                if (tag.startsWith("<p") || tag.startsWith("<P") || tag.startsWith("<br") || tag.startsWith("<BR")) {
                    content = content.replace(tag, "\n");
                } else {
                    content = content.replace(tag, "");
                }
            }

            String[] contents = (title + "\n" + content + "\n本章完\"").split("\n");

            JSONArray contentArray = new JSONArray();
            for (String t:contents) {
                if (t.trim().isEmpty()) {
                    continue;
                }
                contentArray.put(t);
            }

            this.handleTts.addText(new String[]{"0", contents[0], id, title, contentArray.toString(), nextId, preId});  // string[]内容：[0:idx, 1:text播放内容, 2:currentItemId当前id,3:currentTitle当前标题,
            // 4:currentItemContent(jsonArray) 当前章节全部内容, 5:nextItemId下一章id, 6:preId上一章节Id
            int i = 1;
            for (int k = 1; k < contents.length; k++) {
                String t = contents[k];
                if (t.trim().isEmpty()) {
                    continue;
                }
                this.handleTts.addText(new String[]{"" + i, t});
                i++;
            }
            if (sharedPreferences.getString(CacheKey.PLAY_AFTER_REQ_SIGN.name(), "").equals(id)) {
                // 唤醒暗号对上了
                this.handleTts.tryPlayNextText();
            }
            LogUtil.info(TAG, "success get " + reqUrl);

        } catch (Exception ne) {
            LogUtil.info(TAG, "请求接口异常:" + reqUrl + ", " + ne.getMessage(), ne);
            if (tryCount > 0) {
                LogUtil.info(TAG, "再给" + tryCount + "次机会：" + reqUrl, ne);
                try {
                    Thread.sleep(Double.valueOf(15 - Math.pow(2, tryCount)).longValue() * 1000);  // sleep10秒后再尝试
                } catch (InterruptedException e) {
                    LogUtil.info(TAG, "sleep失败:" + reqUrl, ne);
                }
                cacheItem(sharedPreferences, reqUrl, tryCount - 1);
            }
        }
    }
}
